import datetime,math
from jili.price.ta import creat_ta_calcor as ta_frame
from jili.core import load
from jili.tool.get_sysdata import load_sysdata,save_sysdata
from jili.data.data_window import data_window
import os
from copy import deepcopy
from jili.core.printlog import print
#---------------k线字段
#open,high,low,close,volume
#vwap:均价，pos:剩余仓位，updatetime
#使用dict；考虑场景：
def copydict(t):
    r={}
    for k,v in t.items():
        r[k]=v
    return r
bar_keys_rq=load_sysdata("bar_keys_rq")
class kline1m:
    def __init__(self,obj,bars_len=2,ktype="0"):
        self.oncallkey=None
        self.obj=obj
        self.iscall=True
        self.bars_len=bars_len
        self.pretimekey=None
        self.endtimes = []
        self.bar={}
        self.bars = []
        self.onbarcall = []
        self.tas=[]
        self.ktype=ktype
        products0=["IF","IH","IC","IM"]
        products1=["TS","TF","T","TL"]
        product=obj[:2]
        if product in products0:
            self.othertime={
                datetime.time(9,29):(9,31),
                datetime.time(11,30):(11,30),
                datetime.time(15,0):(15,0),
            }
        elif product in products1:
            self.othertime={
                datetime.time(9,29):(9,31),
                datetime.time(11,30):(11,30),
                datetime.time(15, 15): (15, 15)
            }
        else:
            self.othertime={
                datetime.time(20, 59): (21, 1),
                datetime.time(23, 0): (23, 0),
                datetime.time(1, 0): (1, 0),
                datetime.time(2, 30): (2, 30),
                datetime.time(8,59):(9,1),
                datetime.time(10, 15): (10, 15),
                datetime.time(11,30):(11,30),
                datetime.time(15,0):(15,0),
            }
        self.day=None
        self.data_tradetime2=None
        self.check_btimekey=True
        self.isstartday=True
        self.ondata=self.ontick
        #k触发回调规则：1：结束触发，0.实时触发

    def add_ta(self,ta_arg):
        ta0=ta_frame(ta_arg)
        self.tas.append(ta0)
    def __calc_ta(self,bar):
        #print(bar)
        for i in self.tas:
            r = i.onbar(bar)
            #print(r)
            bar.update(r)
        return bar
    def reset(self):
        self.bar={}
        self.bars = []
    def setonbar(self,call):
        self.onbarcall.append(call)

    def ontick(self,t):
        if "obj" in t.keys():
            self.obj=t["obj"]
        timekey0=t["timekey"]
        vv="volume"
        if t[vv] == 0:
            return {}
        # if not self.checktime(timekey0):
        #     return {}
        isend,btimekey=self.getbartimekey(timekey0)
        p=t["lastPrice"]
        if self.bars:
            bar=self.bars[-1]
            if btimekey==bar["timekey"]:
                if bar["high"]<p:
                    bar["high"] = p
                    bar["hightime"] = timekey0
                elif bar["low"] > p:
                    bar["low"] = p
                    bar["lowtime"] = timekey0
                bar["close"]=p
                bar["volume"]=bar["volume"]+t["volume"]
                if "vwap" in t.keys():
                    bar["vwap"]=t["vwap"]
                bar["uptime"]=timekey0
                if self.ktype== "1":
                    if isend:
                        self.__calc_ta(bar)
                        for i in self.onbarcall:
                            i(self.bar)
                elif self.ktype== "0":
                    self.__calc_ta(bar)
                    for i in self.onbarcall:
                        i(self.bar)
            else:
                bar0 = {}
                bar0["timekey"] = btimekey
                bar0["obj"] = self.obj
                if "code" in t.keys():
                    bar0["code"] = t["code"]
                bar0["open"] = p
                bar0["high"] = p
                bar0["low"] = p
                bar0["close"] = p
                bar0["volume"] = t["volume"]
                if "vwap" in t.keys():
                    bar0["vwap"] = t["vwap"]
                bar0["uptime"] = timekey0
                bar0["hightime"] = timekey0
                bar0["lowtime"] = timekey0
                bar0["opentime"] = timekey0
                self.bars.append(bar0)
                if len(self.bars) > self.bars_len:
                    self.bars.pop(0)
                self.bar = bar0
                if self.ktype == "0":
                    self.__calc_ta(self.bar)
                    for i in self.onbarcall:
                        i(self.bar)
        else:
            bar0={}
            bar0["timekey"]=btimekey
            bar0["obj"]=self.obj
            if "code" in t.keys():
                bar0["code"]=t["code"]
            bar0["open"]=p
            bar0["high"]=p
            bar0["low"]=p
            bar0["close"]=p
            bar0["volume"]=t["volume"]
            if "vwap" in t.keys():
                bar0["vwap"] = t["vwap"]
            else:
                bar0["vwap"] = 0
            bar0["uptime"]=timekey0
            bar0["hightime"] = timekey0
            bar0["lowtime"] = timekey0
            bar0["opentime"] = timekey0
            self.bars.append(bar0)
            self.bar=bar0
            if self.ktype == "0":
                self.__calc_ta(self.bar)
                for i in self.onbarcall:
                    i(self.bar)
        return self.bar
    def getbartimekey(self,a):
        t0=datetime.time(a.hour,a.minute)
        if t0 in self.othertime.keys():
            tt=self.othertime[t0]
            b=datetime.datetime(a.year, a.month, a.day, tt[0], tt[1])
            # self.pretimekey = b
            return False,b
        else:
            b = datetime.datetime(a.year, a.month, a.day, a.hour, a.minute)
            if b==self.pretimekey:
                b0 = b + datetime.timedelta(minutes=1)
                self.pretimekey= b0
                return True,b
            else:
                b=b+datetime.timedelta(minutes=1)
                if self.pretimekey is None:
                    self.pretimekey= b
                return False,b
    def checktime(self,a):
        # r=a.time()<=self.endtime
        r=True
        return r
class klinenm:
    #预设:3,5,10,15,30,60
    def __init__(self,obj,period=5,bars_len=2,bar0=None):
        global bar_keys_rq
        self.obj=obj
        self.period=period
        products0 = ["IF", "IH", "IC", "IM"]
        products1 = ["TS", "TF", "T", "TL"]
        product=""
        for i in obj:
            if i.isdigit():
                break
            product=product+i
        if product in products0:
            #240分钟:3,5,10,15,30,60都是240的整数倍,所以直接计算生成
            key="k"+str(period)+"m_0"
            self.bar_keys=bar_keys_rq[key]
        elif product in products1:
            # 240+15分钟:3,5,10,15,30,60都是240的整数倍,所以直接计算生成,15只能满足3,5,15的整除,30,60直接处理成最后一根,10分拆即可
            key = "k" + str(period) + "m_2"
            self.bar_keys = bar_keys_rq[key]
        else:
            key = "k" + str(period) + "m_1"
            self.bar_keys = bar_keys_rq[key]
        self.bar={}
        if bar0 is None:
            self.bars=[]
        else:
            self.bars=[bar0]
        self.bars_len=bars_len
        self.onbarcall = []
        self.tas = []
        self.day=None
        self.data_tradetime2=None
        self.ondata = self.onbar
        self.pretimekey=None
    def add_ta(self, ta_arg):
        ta0 = ta_frame(ta_arg)
        self.tas.append(ta0)

    def __calc_ta(self, bar):
        for i in self.tas:
            r = i.onbar(bar)
            bar.update(r)
        return bar
    def setonbar(self,call):
        self.onbarcall.append(call)
    def getbartimekey(self,timekey):
        time=timekey.time()
        isend=False
        d=None
        for d0,d1 in data_window(self.bar_keys,2):
            if time==d1:
                isend=True
            if d0<d1:
                if d0<time<=d1:
                    d=datetime.datetime(timekey.year,timekey.month,timekey.day,d1.hour,d1.minute)
                    break
            else:
                if d0<time or time<=d1:
                    d=datetime.datetime(timekey.year,timekey.month,timekey.day,d1.hour,d1.minute)
                    break
        return isend,d
    def onbar(self,t):
        if "obj" in t.keys():
            self.obj=t["obj"]
        timekey0 = t["timekey"]
        isend,timekey=self.getbartimekey(timekey0)
        if self.bars:
            bar0=self.bars[-1]
            if timekey==bar0["timekey"]:
                if bar0["high"]<t["high"]:
                    bar0["high"]=t["high"]
                elif bar0["low"] > t["low"]:
                    bar0["low"] = t["low"]
                bar0["close"]=t["close"]
                bar0["volume"]=bar0["volume"]+t["volume"]
                bar0=self.__calc_ta(bar0)
                self.bar = bar0
            else:
                bar0={}
                bar0["timekey"]=timekey
                bar0["obj"]=self.obj
                if "code" in t.keys():
                    bar0["code"] = t["code"]
                bar0["open"]=t["open"]
                bar0["high"]=t["high"]
                bar0["low"]=t["low"]
                bar0["close"]=t["close"]
                bar0["volume"]=t["volume"]
                bar0=self.__calc_ta(bar0)
                self.bars.append(bar0)
                self.bar=bar0
        else:
            bar0={}
            bar0["timekey"]=timekey
            bar0["obj"]=self.obj
            if "code" in t.keys():
                bar0["code"]=t["code"]
            bar0["open"]=t["open"]
            bar0["high"]=t["high"]
            bar0["low"]=t["low"]
            bar0["close"]=t["close"]
            bar0["volume"]=t["volume"]
            bar0=self.__calc_ta(bar0)
            self.bars.append(bar0)
            self.bar=bar0

        if isend:
            for i in self.onbarcall:
                i(self.bar)
        return self.bar
def deal_knm_bar_keys(url,d):
    from jili.dataset import dataset
    from jili.core import save
    from jili.tool import sort_dictlist
    objs={"0":"IF88","1":"au88","2":"T88"}
    bars_keys={}
    for n in [3,5,10,15,30,60]:
        knm="k"+str(n)+"m"
        tick_tool = dataset(product="future", datatype=knm, baseurl=url, region="C", fqtype=None, freq=None,source="rqi",
                            iszip=True)
        for k,obj in objs.items():
            key=knm+"_"+k
            ks=tick_tool.get_data_bydate(obj,d)
            ks=sort_dictlist(ks,True,"timekey")
            if k=="1":
                tt = [datetime.time(21,0)]
            else:
                tt = [datetime.time(9,30)]
            for i in ks:
                tk=i["timekey"]
                tt.append(tk.time())
            bars_keys[key]=tt
    save_sysdata(bars_keys,"bar_keys_rq")

if __name__=="__main__":
    deal_knm_bar_keys(url=r"I:\price",d="20251024")